# coding=UTF-8
import os

from utils import json_util, statisticalutil


# 三个数值的形态
def thr_form(x):
    if len(x) != 3:
        return ''
    if x[0] > x[1] > x[2]:
        return '/'
    if x[0] < x[1] < x[2]:
        return '\\'
    if x[0] >= x[1] and x[1] <= x[2]:
        return 'v'
    if x[0] <= x[1] and x[1] >= x[2]:
        return '^'


# 两个数值和零轴的形态
def zero_form(x1, x2):
    if x1 > 0 and x2 > 0:
        return 'L'
    if x1 < 0 and x2 < 0:
        return 'T'
    if x1 > 0 and x2 < 0:
        return '/'
    if x1 < 0 and x2 > 0:
        return '\\'


# 获取一个最高分
def get_highest_score(form_dict):
    highest = -1
    form = ''
    for key in form_dict.keys():
        score = form_dict[key]['score']
        if score >= highest:
            highest = score
            form = key
    return form_dict[form]


# 使用默认配置的 front
def exam_all_form(x):
    form_dict = {
        '/': {'form': '/', 'score': 0, 'front': 0, 'amplitude': 15},
        '\\': {'form': '\\', 'score': 0, 'front': 0, 'amplitude': 15},
        'L': {'form': 'L', 'score': 0, 'front': 50, 'amplitude': 15},
        '厂': {'form': '厂', 'score': 0, 'front': 70, 'amplitude': 15},
        'V': {'form': 'V', 'score': 0, 'front': 50, 'amplitude': 10},
        'n': {'form': 'n', 'score': 0, 'front': 50, 'amplitude': 10},
    }
    size = len(x)
    if size < 3:
        return form_dict
    max = x[0]
    min = x[0]
    for i in range(1, size):
        if max < x[i]:
            max = x[i]
        if min > x[i]:
            min = x[i]
    for subjects in form_dict.keys():
        form_info = form_dict[subjects]
        if amplitude_check(min, max, form_info['amplitude']) == 0:
            continue
        if subjects == 'L':
            form_info['score'] = exam_l_form(x, min, max, form_info['front'])
        elif subjects == '厂':
            form_info['score'] = exam_chang_form(x, min, max, form_info['front'])
        elif subjects == 'V':
            form_info['score'] = exam_v_form(x, min, max, form_info['front'])
        elif subjects == 'n':
            form_info['score'] = exam_n_form(x, min, max, form_info['front'])
        elif subjects == '\\':
            form_info['score'] = exam_down_form(x, min, max)
        elif subjects == '/':
            form_info['score'] = exam_up_form(x, min, max)
        form_dict[subjects] = form_info
    return form_dict


# 形态测试
# x 数列（最小长度为3）
# front前一段站百分比（就是一竖站总长百分比）
# amplitude 振幅 > 0 为大于当前振奋 <0 为小于当前振奋 按照总长100计算
# subjects 考试科目
def exam_form_score(x, front, amplitude, subjects):
    size = len(x)
    if size < 3:
        return 0
    max = x[0]
    min = x[0]
    for i in range(1, size):
        if max < x[i]:
            max = x[i]
        if min > x[i]:
            min = x[i]
    if amplitude_check(min, max, amplitude) == 0:
        return 0
    if subjects == 'L':
        return exam_l_form(x, min, max, front)
    elif subjects == '厂':
        return exam_chang_form(x, min, max, front)
    elif subjects == 'V':
        return exam_v_form(x, min, max, front)
    elif subjects == 'n':
        return exam_n_form(x, min, max, front)
    elif subjects == '\\':
        return exam_down_form(x, min, max)
    elif subjects == '/':
        return exam_up_form(x, min, max)
    else:
        return 0


# 振幅检查
# amplitude 振幅 > 0 为大于当前振奋 <0 为小于当前振奋 按照总长100计算
def amplitude_check(min, max, amplitude):
    rise_prop = round((max - min) / min, 4) * 100
    if amplitude > 0 and rise_prop < amplitude or amplitude < 0 and rise_prop > (-amplitude):
        return 0
    return 1


# L形态测试
# x 数列（最小长度为3）
# min 数列最大值
# max 数列最小值
# front前一段站百分比
def exam_l_form(x, min, max, front):
    size = len(x)
    compare_params = []
    compare_size = round(size * front / 100)
    diff_p = round((max - min) / compare_size, 4)
    param = max
    compare_params.append(param)
    for i in range(size - 1):
        if i < compare_size:
            param -= diff_p
        compare_params.append(param)
    return round(statisticalutil.correlation(x, compare_params), 4)


# 厂形态测试
# x 数列（最小长度为3）
# min 数列最大值
# max 数列最小值
# front前一段站百分比
def exam_chang_form(x, min, max, front):
    size = len(x)
    compare_params = []
    compare_size = round(size * front / 100)
    diff_p = round((max - min) / compare_size, 4)
    param = min
    compare_params.append(param)
    for i in range(size - 1):
        if i < compare_size:
            param += diff_p
        compare_params.append(param)
    return round(statisticalutil.correlation(x, compare_params), 4)


# V形态测试
# x 数列（最小长度为3）
# min 数列最大值
# max 数列最小值
# front前一段站百分比
def exam_v_form(x, min, max, front):
    size = len(x)
    compare_params = []
    compare_size = round(size * front / 100) - 1
    diff_p = round((max - min) / compare_size, 4)
    param = max
    compare_params.append(param)
    for i in range(size - 1):
        if i < compare_size:
            param -= diff_p
        else:
            param += diff_p
        compare_params.append(param)
    return round(statisticalutil.correlation(x, compare_params), 4)


# n形态测试
# x 数列（最小长度为3）
# min 数列最大值
# max 数列最小值
# front前一段站百分比
def exam_n_form(x, min, max, front):
    size = len(x)
    compare_params = []
    compare_size = round(size * front / 100) - 1
    diff_p = round((max - min) / compare_size, 4)
    param = min
    compare_params.append(param)
    for i in range(size - 1):
        if i < compare_size:
            param += diff_p
        else:
            param -= diff_p
        compare_params.append(param)
    return round(statisticalutil.correlation(x, compare_params), 4)


# \形态测试
# x 数列（最小长度为3）
# min 数列最大值
# max 数列最小值
# front前一段站百分比
def exam_down_form(x, min, max):
    size = len(x)
    compare_params = []
    diff_p = round((max - min) / (size - 1), 4)
    param = max
    compare_params.append(param)
    for i in range(size - 1):
        param -= diff_p
        compare_params.append(param)
    return round(statisticalutil.correlation(x, compare_params), 4)


# /形态测试
# x 数列（最小长度为3）
# min 数列最大值
# max 数列最小值
# front前一段站百分比
def exam_up_form(x, min, max):
    size = len(x)
    compare_params = []
    diff_p = round((max - min) / (size - 1), 4)
    param = min
    compare_params.append(param)
    for i in range(size - 1):
        param += diff_p
        compare_params.append(param)
    return round(statisticalutil.correlation(x, compare_params), 4)


# todo 扩展 N 形态 和 s形态

# 判断数列形态
# 分数小于0.5的不做参考
def judge_form(x):
    form_dict = {}
    size = len(x)
    max = x[0]
    min = x[0]
    sum = x[0]
    for i in range(1, size):
        if max < x[i]:
            max = x[i]
        if min > x[i]:
            min = x[i]
        sum += x[i]

    # 上升形态 '/'
    param = min
    compare_params = []
    compare_params.append(param)
    diff_param = round((max - min) / size, 4)
    for i in range(size - 1):
        param = param + diff_param
        compare_params.append(param)
    form_dict['/'] = round(statisticalutil.correlation(x, compare_params), 4)
    # 上升形态 '\\'
    param = max
    compare_params = []
    compare_params.append(param)
    diff_param = round((max - min) / size, 4)
    for i in range(size - 1):
        param = param - diff_param
        compare_params.append(param)
    form_dict['\\'] = round(statisticalutil.correlation(x, compare_params), 4)
    # 形态 'v'
    param = max
    compare_params = []
    compare_params.append(param)
    compare_size = int(size / 2)
    diff_param = round((max - min) / compare_size, 4)
    for i in range(size - 1):
        if i < compare_size:
            param = param - diff_param
        else:
            param = param + diff_param
        compare_params.append(param)
    form_dict['v'] = round(statisticalutil.correlation(x, compare_params), 4)
    # 形态 '^'
    param = min
    compare_params = []
    compare_params.append(param)
    compare_size = int(size / 2)
    diff_param = round((max - min) / compare_size, 4)
    for i in range(size - 1):
        if i < compare_size:
            param = param + diff_param
        else:
            param = param - diff_param
        compare_params.append(param)
    form_dict['^'] = round(statisticalutil.correlation(x, compare_params), 4)
    score = 0
    score_key = ''
    for key in form_dict.keys():
        if score < form_dict[key]:
            score = form_dict[key]
            score_key = key
    # 形态 'N'
    param = min
    compare_params = []
    compare_params.append(param)
    compare_size = int(size / 3)
    diff_param = round((max - min) / compare_size, 4)
    for i in range(size - 1):
        if i < compare_size:
            param = param + diff_param
        elif i < compare_size * 2:
            param = param - diff_param
        else:
            param = param + diff_param
        compare_params.append(param)
    form_dict['N'] = round(statisticalutil.correlation(x, compare_params), 4)

    # 形态 's'
    param = max
    compare_params = []
    compare_params.append(param)
    compare_size = int(size / 3)
    diff_param = round((max - min) / compare_size, 4)
    for i in range(size - 1):
        if i < compare_size:
            param = param - diff_param
        elif i < compare_size * 2:
            param = param + diff_param
        else:
            param = param - diff_param
        compare_params.append(param)
    form_dict['s'] = round(statisticalutil.correlation(x, compare_params), 4)
    print(form_dict)
    score = 0
    score_key = ''
    for key in form_dict.keys():
        if score < form_dict[key]:
            score = form_dict[key]
            score_key = key
    return {score_key: score}


# 生成一个x数列
def gen_x(list_info, key):
    x = []
    for info in list_info:
        x.append(float(json_util.info_to_json(info)[key]))
    return x


# 判断数列形态
# 分数小于0.5的不做参考
# ex_form:期望的形态
def judge_form_expect(x, ex_form):
    size = len(x)
    if size < 4:
        return 0
    max = x[0]
    min = x[0]
    sum = x[0]
    for i in range(1, size):
        if max < x[i]:
            max = x[i]
        if min > x[i]:
            min = x[i]
        sum += x[i]
    score = 0
    if ex_form == '厂':  # 厂形态7:3形态
        rise_prop = round((max - min) / min, 4) * 100
        if rise_prop < 15:  # 没有15的涨幅不考虑
            return 0
        compare_params = []
        compare_size = round(size * 7 / 10)  # 四舍五入
        diff_p = round((max - min) / compare_size, 4)
        param = min
        compare_params.append(param)
        for i in range(size - 1):
            if i < compare_size:
                param += diff_p
            compare_params.append(param)
        score = round(statisticalutil.correlation(x, compare_params), 4)
    if ex_form == 'L':  # L形态7:3形态
        rise_prop = round((max - min) / min, 4) * 100
        if rise_prop < 15:  # 没有15的涨幅不考虑
            return 0
        compare_params = []
        compare_size = round(size * 7 / 10)  # 四舍五入
        diff_p = round((max - min) / compare_size, 4)
        param = min
        compare_params.append(param)
        for i in range(size - 1):
            if i < compare_size:
                param += diff_p
            compare_params.append(param)
        score = round(statisticalutil.correlation(x, compare_params), 4)

    return score


if __name__ == '__main__':
    s1 = exam_form_score([6, 5, 4, 3, 2, 1, 2, 3, 4, 5], 60, 400, 'V')
    s4 = exam_form_score([6, 5, 4, 3, 2, 1, 2, 3, 4, 5], 60, 400, 'n')
    s2 = exam_form_score([8, 7, 6, 5, 4, 3, 2, 1, 1, 1], 70, 400, 'L')
    s3 = exam_form_score([1, 2, 3, 4, 5, 6, 7, 7, 7, 7], 60, 400, '厂')
    s5 = exam_form_score([9, 8, 7, 6, 5, 4, 3, 2, 1], 0, 400, '\\')
    s6 = exam_form_score([9, 8, 7, 6, 5, 4, 3, 2, 1], 0, 400, '/')
    s7 = exam_form_score([1, 2, 3, 4, 5, 6, 7, 8, 9], 0, 400, '/')
    print()
